﻿#include <glog/logging.h>
#include "constant.h"
#include "camera/camera.h"
#include "manager/config_manager.h"

Camera::Camera() {
    is_open = false;
    is_run = false;
    invalid_frame_count = 0;
}

Camera::~Camera() {
}

bool Camera::open(const char *rtsp_addr) {
    AppConfig * app_config = ConfigManager::getInstance()->get_app_config();
    bool live_camera = app_config->live_camera;

    if (live_camera == true) {
        m_address = QByteArray(rtsp_addr);
        if (!capture.open(rtsp_addr)) {
            LOG(INFO) << "Camera | open camera error";
            is_open  = false;
        } else {
            LOG(INFO) << "Camera | open camera success";
            is_open = true;
        }
    } else {
        if (!capture.open(VIDEO_SOURCE_FILE)) {
            LOG(INFO) << "Camera | open file error";
            is_open  = false;
        } else {
            LOG(INFO) << "Camera | open file success";
            is_open = true;
        }
    }
    return is_open;
}

bool Camera::reopen() {
    AppConfig * app_config = ConfigManager::getInstance()->get_app_config();
    bool live_camera = app_config->live_camera;

    if (live_camera == true) {
        if (!capture.open(m_address.data())) {
            LOG(INFO) << "Camera | reopen camera error";
            is_open  = false;
        } else {
            LOG(INFO) << "Camera | reopen camera success";
            is_open = true;
        }
    } else {
        if (!capture.open(VIDEO_SOURCE_FILE)) {
            LOG(INFO) << "Camera | reopen file error";
            is_open  = false;
        } else {
            LOG(INFO) << "Camera | reopen file success";
            is_open = true;
        }
    }
    return is_open;
}

bool Camera::is_cam_open() {
    return is_open;
}

bool Camera::start_grab() {
    if (is_open == false) {
        LOG(INFO) << "Camera | start_grab | camera is not open";
        is_run = true;
        start();
        return false;
    } else {
        LOG(INFO) << "Camera | start_grab | start grab thread";
        is_run = true;
        start();
        return true;
    }
}

void Camera::stop_grab() {
    is_run = false;
}

void Camera::run() {
    AppConfig * app_config = ConfigManager::getInstance()->get_app_config();
    bool live_camera = app_config->live_camera;

    int frame_count_total =  0;
    int frame_delay = 0;
    int frame_count = 0;
    if (live_camera == false) {
        frame_count_total = capture.get(CV_CAP_PROP_FRAME_COUNT);
        frame_delay = 1000.0 / capture.get(CV_CAP_PROP_FPS);
        LOG(INFO) << "Camera | run | frame_count_total" << frame_count_total
                 << "frame_delay" << frame_delay;
    }

    Mat frame;
    while (is_run) {
        if (is_open == false) {
            reopen();
        }
        capture >> frame;
        if (frame.cols > 0 && frame.rows > 0) {
            invalid_frame_count = 0;
            emit image_ready(QSharedPointer<Mat>(new Mat(frame)));
        } else {
            LOG(INFO) << "Camera | run | invalid frame";
            if (invalid_frame_count++ > 10) {
                LOG(INFO) << "Camera | run | invalid frame too many, reopen camera";
                is_open = false;
                invalid_frame_count = 0;
            }
        }
        if (live_camera == false) {
            frame_count++;
            if (frame_count >= frame_count_total) {
                frame_count = 0;
                capture.set(CV_CAP_PROP_POS_FRAMES, 0);
            }
             QThread::msleep(frame_delay);
        }
    }
}
